package com.company.genealogy.web.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.company.genealogy.common.constant.ApiCodeEnum;
import com.company.genealogy.common.result.ApiResponse;
import com.company.genealogy.web.dto.UserCreateDTO;
import com.company.genealogy.web.entity.Role;
import com.company.genealogy.web.entity.User;
import com.company.genealogy.web.entity.UserRole;
import com.company.genealogy.web.mapper.UserRoleMapper;
import com.company.genealogy.web.service.RoleService;
import com.company.genealogy.web.service.UserService;
import com.company.genealogy.web.vo.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户管理控制器
 * 
 * 提供用户信息的增删改查、角色管理、权限控制等功能。
 * 支持用户基本信息管理、角色分配、密码重置等操作。
 * 
 * 主要功能：
 * - 用户基本信息管理（增删改查）
 * - 用户角色分配和管理
 * - 用户状态管理
 * - 密码加密和重置
 * - 用户权限查询
 * 
 * 安全特性：
 * - 密码加密存储
 * - 基于角色的权限控制
 * - 用户状态验证
 * 
 * @author chenzhixiang
 * @version 1.0
 * @since 2024-01-01
 */
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
    
    /**
     * 用户服务接口
     */
    @Autowired
    private UserService userService;

    /**
     * 角色服务接口
     */
    @Autowired
    private RoleService roleService;

    /**
     * 用户角色关系数据访问对象
     */
    @Autowired
    private UserRoleMapper userRoleMapper;

    /**
     * 密码加密器
     */
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    /**
     * 获取当前用户信息
     * 
     * 从安全上下文中获取当前登录用户的信息。
     * 
     * @return 当前用户信息
     */
    @GetMapping("/me")
    public ApiResponse<User> getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String userIdStr = authentication.getName();
        Long userId = Long.parseLong(userIdStr);
        User user = userService.getById(userId);
        return ApiResponse.success(ApiCodeEnum.SUCCESS, user);
    }
    
    /**
     * 分页查询用户列表
     * 
     * 支持按用户名、用户类型等条件进行筛选查询。
     * 返回的用户信息包含角色信息。
     * 
     * @param page 页码，默认为1
     * @param size 每页大小，默认为10
     * @param username 用户名，支持模糊查询，可选
     * @param userType 用户类型，可选
     * @return 分页的用户列表
     */
    @GetMapping
    public ApiResponse<IPage<UserVO>> list(@RequestParam(defaultValue = "1") int page,
                                       @RequestParam(defaultValue = "10") int size,
                                       @RequestParam(required = false) String username,
                                       @RequestParam(required = false) String userType) {
        Page<User> p = new Page<>(page, size);
        
        /**
         * 构建查询条件
         * 根据传入的参数动态构建查询条件
         */
        com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<User> queryWrapper = new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<>();
        
        if (username != null && !username.trim().isEmpty()) {
            queryWrapper.like("username", username.trim());
        }
        
        if (userType != null && !userType.trim().isEmpty()) {
            queryWrapper.eq("user_type", userType.trim());
        }
        
        IPage<User> userPage = userService.page(p, queryWrapper);
        
        /**
         * 批量查询角色信息
         * 提高查询效率，避免N+1查询问题
         */
        List<Long> userIds = userPage.getRecords().stream().map(User::getId).collect(Collectors.toList());
        Map<Long, List<String>> userRolesMap = userIds.isEmpty() ? java.util.Collections.emptyMap() :
            userIds.stream().collect(Collectors.toMap(
                id -> id,
                id -> roleService.getRolesByUserId(id).stream().map(Role::getName).collect(Collectors.toList())
            ));
        List<UserVO> voList = userPage.getRecords().stream().map(u -> {
            UserVO vo = new UserVO();
            vo.setId(u.getId());
            vo.setUserType(u.getUserType());
            vo.setUsername(u.getUsername());
            vo.setNickname(u.getNickname());
            vo.setAvatar(u.getAvatar());
            vo.setClanId(u.getClanId());
            vo.setBranchId(u.getBranchId());
            vo.setRoles(userRolesMap.getOrDefault(u.getId(), java.util.Collections.emptyList()));
            vo.setStatus(u.getStatus());
            return vo;
        }).collect(Collectors.toList());
        IPage<UserVO> voPage = new Page<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal());
        voPage.setRecords(voList);
        return ApiResponse.success(ApiCodeEnum.SUCCESS, voPage);
    }
    
    /**
     * 创建新用户
     * 
     * 创建用户基本信息并分配角色。
     * 密码会自动加密存储。
     * 
     * @param dto 用户创建数据传输对象
     * @return 创建成功的用户信息
     */
    @PostMapping
    public ApiResponse<User> create(@RequestBody UserCreateDTO dto) {
        /**
         * 构建User对象
         * 将DTO中的信息转换为User实体
         */
        User user = new User();
        user.setUserType(dto.getUserType());
        user.setUsername(dto.getUsername());
        user.setNickname(dto.getNickname());
        user.setClanId(dto.getClanId());
        user.setBranchId(dto.getBranchId());
        user.setStatus(dto.getStatus());
        
        /**
         * 密码加密（示例，实际应用请用更安全方式）
         * 使用Spring Security的PasswordEncoder进行加密
         */
        user.setPasswordHash(passwordEncoder.encode(dto.getPassword()));
        userService.save(user);
        
        /**
         * 保存用户角色关系
         * 如果指定了角色ID列表，则创建用户角色关联
         */
        if (dto.getRoleIds() != null && !dto.getRoleIds().isEmpty()) {
            for (Long roleId : dto.getRoleIds()) {
                UserRole userRole = new UserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(roleId);
                userRoleMapper.insert(userRole);
            }
        }
        return ApiResponse.success(ApiCodeEnum.SUCCESS, user);
    }
    
    /**
     * 获取用户详细信息
     * 
     * 根据用户ID获取用户的完整信息。
     * 
     * @param id 用户ID
     * @return 用户详细信息
     */
    @GetMapping("/{id}")
    public ApiResponse<User> detail(@PathVariable Long id) {
        User user = userService.getById(id);
        return ApiResponse.success(ApiCodeEnum.SUCCESS, user);
    }
    
    /**
     * 更新用户信息
     * 
     * 支持部分字段更新，包括密码重置功能。
     * 
     * @param id 用户ID
     * @param updateData 更新的字段数据
     * @return 更新操作结果
     */
    @PutMapping("/{id}")
    public ApiResponse<Void> update(@PathVariable Long id, @RequestBody Map<String, Object> updateData) {
        User user = userService.getById(id);
        if (user == null) {
            return ApiResponse.fail("用户不存在");
        }
        
        // 处理密码重置
        if (updateData.containsKey("password")) {
            String newPassword = (String) updateData.get("password");
            user.setPasswordHash(passwordEncoder.encode(newPassword));
        }
        
        // 处理其他字段更新
        if (updateData.containsKey("nickname")) {
            user.setNickname((String) updateData.get("nickname"));
        }
        if (updateData.containsKey("userType")) {
            user.setUserType((String) updateData.get("userType"));
        }
        if (updateData.containsKey("status")) {
            user.setStatus((Integer) updateData.get("status"));
        }
        if (updateData.containsKey("avatar")) {
            user.setAvatar((String) updateData.get("avatar"));
        }
        if (updateData.containsKey("clanId")) {
            Object clanIdObj = updateData.get("clanId");
            if (clanIdObj != null) {
                user.setClanId(Long.parseLong(clanIdObj.toString()));
            } else {
                user.setClanId(null);
            }
        }
        if (updateData.containsKey("branchId")) {
            Object branchIdObj = updateData.get("branchId");
            if (branchIdObj != null) {
                user.setBranchId(Long.parseLong(branchIdObj.toString()));
            } else {
                user.setBranchId(null);
            }
        }
        
        userService.updateById(user);
        return ApiResponse.success(ApiCodeEnum.SUCCESS, null);
    }
    
    // 删除用户
    @DeleteMapping("/{id}")
    public ApiResponse<Void> delete(@PathVariable Long id) {
        userService.removeById(id);
        return ApiResponse.success(ApiCodeEnum.SUCCESS, null);
    }
    
    // 获取用户角色（由id改为username）
    @GetMapping("/by-username/{username}/roles")
    public ApiResponse<List<Role>> getUserRolesByUsername(@PathVariable String username) {
        User user = userService.getByUsername(username);
        if (user == null) {
            return ApiResponse.fail("用户不存在");
        }
        List<Role> roles = roleService.getRolesByUserId(user.getId());
        return ApiResponse.success(ApiCodeEnum.SUCCESS, roles);
    }

    // 设置用户角色（由id改为username）
    @PostMapping("/by-username/{username}/roles")
    public ApiResponse<Void> setUserRolesByUsername(@PathVariable String username, @RequestBody List<Long> roleIds) {
        User user = userService.getByUsername(username);
        if (user == null) {
            return ApiResponse.fail("用户不存在");
        }
        // 先删除用户现有角色
        userRoleMapper.delete(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<UserRole>()
                .eq("user_id", user.getId()));
        // 添加新角色
        for (Long roleId : roleIds) {
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(roleId);
            userRoleMapper.insert(userRole);
        }
        return ApiResponse.success(ApiCodeEnum.SUCCESS, null);
    }
    
    // 获取用户角色（ID方式，保持兼容性）
    @GetMapping("/{id}/roles")
    public ApiResponse<List<Role>> getUserRoles(@PathVariable Long id) {
        List<Role> roles = roleService.getRolesByUserId(id);
        return ApiResponse.success(ApiCodeEnum.SUCCESS, roles);
    }

    // 设置用户角色（ID方式，保持兼容性）
    @PostMapping("/{id}/roles")
    public ApiResponse<Void> setUserRoles(@PathVariable Long id, @RequestBody List<Long> roleIds) {
        // 先删除用户现有角色
        userRoleMapper.delete(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<UserRole>()
                .eq("user_id", id));
        // 添加新角色
        for (Long roleId : roleIds) {
            UserRole userRole = new UserRole();
            userRole.setUserId(id);
            userRole.setRoleId(roleId);
            userRoleMapper.insert(userRole);
        }
        return ApiResponse.success(ApiCodeEnum.SUCCESS, null);
    }
} 